package com.mspbots.rule.exceptions.cw;

import cn.hutool.core.util.StrUtil;
import com.mspbots.cw.request.TenantTimeEntryDTO;
import lombok.extern.slf4j.Slf4j;
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * com.mspbots.rule.exceptions.timeentry.LateTimeEntry
 *
 * @author Jun Zhou
 * @date 14:09 2019/7/1
 **/
@Slf4j
@Rule(name = "LateTimeEntry", description = "Dear [User], You just created the time entry [time entry link] [time difference] after the time entry happened, per company policy, you should record the time entry in real time, means no later than 5 minutes after the time entry’s end time.")
public class LateTimeEntry extends CwBaseRule implements IcwBaseRule {


    @Condition
    @Override
    public boolean condition(@Fact(FACT) TenantTimeEntryDTO entry) {
        try {
            if (!setUserMapping(entry.getTenantUserId()) || super.checkMessage(entry)) {
                return false;
            }

            if ("onsite".equalsIgnoreCase(entry.getExtend().findPath("workType").get("name").asText())
                    || entry.getExtend().findPath("workType").get("name").asText().contains("Delivery") ||
                    "travel".equalsIgnoreCase(entry.getExtend().findPath("workType").get("name").asText())) {
                return entry.getEndDate().plusHours(2).isBefore(entry.getEnteredDate());
            }


            return entry.getEndDate().plusMinutes(this.tenantRuleDTO.getRuleParams().get("LATETIME").asInt(5) + 1).isBefore(entry.getEnteredDate());
        } catch (Exception e) {
            log.error("LateTimeEntry rule execute error [{}] : {}", e.getStackTrace()[0].getLineNumber(), e.getMessage());
        }
        return false;
    }

    @Action
    @Override
    public void action(@Fact(FACT) TenantTimeEntryDTO entry) {
        String template = StringUtils.isEmpty(this.tenantRuleDTO.getTemplate()) ?
                this.tenantRuleDTO.getSysTemplate() : this.tenantRuleDTO.getTemplate();

        if (tenantUserMappingDTO != null) {
            Duration between = Duration.between(entry.getEndDate(), entry.getEnteredDate());


            String timeStr = "";


            if (between.toDays() > 0) {
                if (between.toDays() == 1) {
                    timeStr = between.toDays() + " day ";
                } else {
                    timeStr = between.toDays() + " days ";
                }

            }

            if (between.toHoursPart() > 0) {
                if (between.toHoursPart() == 1) {
                    timeStr += between.toHoursPart() + " hour ";
                } else {
                    timeStr += between.toHoursPart() + " hours ";
                }

            }

            if (between.toMinutesPart() > 0) {
                if (between.toMinutesPart() == 1) {
                    timeStr += between.toMinutesPart() + " min ";
                } else {
                    timeStr += between.toMinutesPart() + " mins ";
                }
            }


            String timeEntryLink = "<a href='https://" + getConfiguration(KEYWORD_WISE_SITE) + "/v4_6_release/ConnectWise.aspx?routeTo=TimeEntryFV&recid=" + entry.getCwTid() + "' >" + entry.getCwTid() + "</a>";


            String lateTime = this.tenantRuleDTO.getRuleParams().get("LATETIME").asText();
            if ("onsite".equalsIgnoreCase(entry.getExtend().findPath("workType").get("name").asText())
                    || entry.getExtend().findPath("workType").get("name").asText().contains("Delivery") ||
                    "travel".equalsIgnoreCase(entry.getExtend().findPath("workType").get("name").asText())) {
                lateTime = "2 hours";
            }
            if ("onsite".equalsIgnoreCase(entry.getExtend().findPath("workType").get("name").asText())) {
                timeEntryLink += " onsite";
            } else if (entry.getExtend().findPath("workType").get("name").asText().contains("Delivery")) {
                timeEntryLink += " PickUp/Delivery";
            } else if ("travel".equalsIgnoreCase(entry.getExtend().findPath("workType").get("name").asText())) {
                timeEntryLink += " travel";
            }


            Map<String, Object> params = new HashMap<>(16);
            params.put("USER", tenantUserMappingDTO.getFirstName());
            params.put("CWTID", timeEntryLink);
            params.put("CREATE_TIME", styleParam(timeStr));
            params.put("LATETIME", styleParam(lateTime));
            String message = StrUtil.format(template, params);

            messages.setMessage(message + "<br>" + suffixEscalation() + suffixMessage(entry.getCwTid(), entry.getEnteredDate()));
            messages.setBusinessId(entry.getCwTid());
            messages.setTimeEntryId(entry.getCwTid());
            this.insertMessage();

        } else {
            log.error("no user mapping for tenant_user_id [{}]", entry.getTenantUserId());
        }
    }


}
